#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/event.h>

#define MAX_EVENTS 2
typedef struct thread_param{
    int isockfd;
    int iclient_addr_len;
    struct sockaddr_in * addr_client;
}thread_param;

void * sub_thread_handle_connection(void *arg)
{
    pthread_t tid_cur = pthread_self();
    printf("sub thread:%d start\n",tid_cur);
    
    thread_param *param = (thread_param *)arg;
    int iclient_socket = param->isockfd;
    struct sockaddr_in *client_addr = param->addr_client;
    socklen_t iclient_addr_len = param->iclient_addr_len;
    getpeername(iclient_socket,(struct sockaddr *)client_addr,&iclient_addr_len);
    char szip[50] = {0};
    int iport = ntohs(client_addr->sin_port);
    inet_ntop(AF_INET,&client_addr->sin_addr,szip,sizeof(szip));
    printf("sub thread:%d new client->%s:%d  sock:%d  \n",tid_cur,szip,iport,iclient_socket);
    char buffer[1024] = {0};
    ssize_t bytes_received = 0;
    // 读取客户端发送的数据
    int i = 0;
    while (bytes_received = recv(iclient_socket, buffer, sizeof(buffer), 0))
    {
        if (bytes_received < 0)
        {
            perror("client %s:%d disconnect on thread:%d with socketfd:%d \n");
            break;
        }
        else
        {
            // 处理收到的数据
            printf("sub thread:%lldd receive client->%s:%d  sock:%d  msg:%s\n",(long long)tid_cur,szip,iport,iclient_socket,buffer);
            char szserverback[30] = {0};
            sprintf(szserverback, "server back %d",i++);
            int iret = send(iclient_socket, szserverback, strlen(szserverback), 0);
            printf("sub thread:%lldd send client->%s:%d  sock:%d  msg:%s\n",(long long)tid_cur,szip,iport,iclient_socket,szserverback);
        }
        memset(buffer, 0, 1024);
    }

    printf("sub thread:%lldd stop client->%s:%d  sock:%d  \n",(long long)tid_cur,szip,iport,iclient_socket);
    close(iclient_socket);
    return NULL;
}

int main(int argc ,char* argv[])
{
    int server_socket;
    int iserver_listen_port = 8888;
    if (argc>=2)
        iserver_listen_port = atoi(argv[1]);
    struct sockaddr_in6 server_addr;
    struct sockaddr_in client_addr;
    
    int isIpv6Only =  0;

    // 创建 IPv6 TCP socket
    server_socket = socket(AF_INET6, SOCK_STREAM, 0);
    if (server_socket == -1) {
        perror("socket");
        return 1;
    }

    // 设置 socket 支持 IPv4 映射到 IPv6 地址
    if (setsockopt(server_socket, IPPROTO_IPV6, IPV6_V6ONLY, &isIpv6Only, sizeof(int)) == -1) {
        perror("setsockopt");
        return 1;
    }

    // 绑定地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin6_family = AF_INET6;
    server_addr.sin6_port = htons(iserver_listen_port);
    server_addr.sin6_addr = in6addr_any;

    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        return 1;
    }

    // 开始监听
    if (listen(server_socket, 5) == -1) {
        perror("listen");
        return 1;
    }

    // 接受连接并处理
    int kq = kqueue();
    if (kq == -1)
    {
        perror("kqueue");
        return 1;
    }
    // 在这里添加你的连接处理逻辑
    printf("server start listening at port:%d\n",iserver_listen_port);
    struct kevent events[MAX_EVENTS];
    struct kevent event;
    EV_SET(&event, server_socket, EVFILT_READ, EV_ADD, 0, 0, NULL);

    if (kevent(kq, &event, 1, NULL, 0, NULL) == -1)
    {
        perror("kevent");
        return 1;
    }

    while (1)
    {
        int event_count = kevent(kq, NULL, 0, events, MAX_EVENTS, NULL);
        if (event_count == -1)
        {
            perror("kevent");
            return 1;
        }

        for (int i = 0; i < event_count; i++)
        {
            if (events[i].ident == server_socket)
            {
                // 有新连接
                int client_addr_len;
                int client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &client_addr_len);
                if (client_socket == -1)
                {
                    perror("accept");
                }
                else
                {
                    // 创建新线程来处理连接
                    thread_param param;
                    param.isockfd = client_socket;
                    param.addr_client =&client_addr;
                    param.iclient_addr_len = client_addr_len;
                    
                    getpeername(client_socket,(struct sockaddr *)&client_addr,&client_addr_len);
                    char ip[50]={0};
                    int iPort = ntohs(client_addr.sin_port);
                    inet_ntop(AF_INET,&client_addr.sin_addr,ip,sizeof(ip));
                    
                    pthread_t tid;
                    pthread_create(&tid, NULL, sub_thread_handle_connection, &param);
                    printf("server main thread accept new client from->%s:%d,and create new thread %d\n",ip,iPort,tid);
                    pthread_detach(tid); // 线程分离，结束时自动回收资源
                }
            }
        }
    }
    // 关闭 socket
    close(server_socket);
    return 0;
}